using System;
using System.IO;

namespace Uniloader.Managers
{
    /// <summary>
    /// Abstract interface for a data transfer task.
    /// </summary>
    public abstract class TransferTask
    {
        private TransferManager manager;
        /// <summary>
        /// The object which is managing this task.
        /// </summary>
        public TransferManager Manager
        {
            get { return manager; }
            internal set { manager = value; }
        }

        #region Start/Stop/Pause/Resume
        /// <summary>
        /// Start downloading.
        /// </summary>
        public abstract void Start();

        /// <summary>
        /// Stop the download.
        /// </summary>
        public abstract void Stop();

        /// <summary>
        /// Pause the download for a short period.
        /// </summary>
        /// <exception cref="System.NotSupportedException"/>
        public virtual void Pause()
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Resume a paused download.
        /// </summary>
        /// <exception cref="System.NotSupportedException"/>
        public virtual void Resume()
        {
            throw new NotSupportedException();
            
        }

        /// <summary>
        /// Returns true if the underlying transfer mechanism supports 
        /// pausing/resuming of transfers, false otherwise.
        /// </summary>
        public virtual bool PauseSupported
        {
            get { return false; }
        }

        /// <summary>
        /// Stop the task and commit data and metadata to persistent storage
        /// such that the task may be resumed later.
        /// </summary>
        public abstract void Suspend();

        #endregion

        #region Public Properties

        /// <summary>
        /// Human readable name of the download task.
        /// </summary>
        public abstract string DisplayName { get; }

        /// <summary>
        /// Data which defines the transfer task. (URL, torrent file, etc...)
        /// </summary>
        public abstract object TransmisionMetadata { get; }

        /// <summary>
        /// Local file or directory containing the data.
        /// </summary>
        public abstract FileSystemInfo LocalData { get; }

        /// <summary>
        /// Amount of data to send before the task is finished.
        /// </summary>
        public abstract long BytesSendTarget { get; }

        /// <summary>
        /// Amount of data to receive before the task is finished.
        /// </summary>
        public abstract long BytesReceiveTarget { get; }

        /// <summary>
        /// Total data bytes sent by this task.
        /// </summary>
        public abstract long BytesSent { get; }

        /// <summary>
        /// Total data bytes received by this task.
        /// </summary>
        public abstract long BytesReceived { get; }

        /// <summary>
        /// Fractional representation of progress on a scale from 0 to 1.
        /// </summary>
        public abstract double Progress { get; }

        /// <summary>
        /// Estimated time to completion.
        /// </summary>
        public abstract TimeSpan RemainingTime { get; }
        
        /// <summary>
        /// Represents the current user set state of the task.
        /// </summary>
        public abstract TaskState TaskState { get; }

        #endregion
    }
}
